package net.gcmz.zrqblog.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import net.gcmz.zrqblog.entity.User;
import net.gcmz.zrqblog.repository.UserRepository;
import net.gcmz.zrqblog.service.UserService;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 *  用户逻辑操作接口实现
 *  
 * @author zhangrongquan
 * @since 2014-12-11
 */

@Service
public class UserServiceImpl implements UserService {

	@Resource
	public UserRepository userRepository;

	@Override
	public User findOneByName(final String name) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				Predicate _name = criteriaBuilder.equal(root.get("name"), name);
				return criteriaBuilder.and(_name);
			}
		};
		return userRepository.findOne(specification);
	}

	@Override
	public Page<User> findAllByLargeThanId(final Long id, int page, int count,
			Sort sort) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				Path<Long> $id = root.get("id");
				Predicate _id = criteriaBuilder.gt($id, id);
				return criteriaBuilder.and(_id);
			}
		};
		Pageable pageable = new PageRequest(page - 1, count, sort);
		return userRepository.findAll(specification, pageable);
	}

	@Override
	public User findAllByIdAndName(final Long id, final String name) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicates = new ArrayList<Predicate>();
				Path<Long> $id = root.get("id");
				Predicate _id = criteriaBuilder.equal($id, id);
				predicates.add(_id);
				Path<Long> $name = root.get("name");
				Predicate _name = criteriaBuilder.equal($name, name);
				predicates.add(_name);
				return criteriaBuilder.and(predicates
						.toArray(new Predicate[] {}));
			}
		};
		return userRepository.findOne(specification);
	}

	@Override
	public Page<User> findAllByLikeName(final String name, int page, int count) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				Path<String> _name = root.get("name");
				Predicate _key = criteriaBuilder.like(_name, "%" + name + "%");
				return criteriaBuilder.and(_key);
			}
		};
		Sort sort = new Sort(Direction.DESC, "id");
		Pageable pageable = new PageRequest(page - 1, count, sort);
		return userRepository.findAll(specification, pageable);
	}

	@Override
	public Page<User> findAllByInIds(final List<Long> ids) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				return criteriaBuilder.in(root.get("id")).value(ids);
			}
		};
		int page = 1;
		int count = ids.size();
		Sort sort = new Sort(Direction.DESC, "id");
		Pageable pageable = new PageRequest(page - 1, count, sort);
		return userRepository.findAll(specification, pageable);
	}

	@Override
	public List<User> findAllByIds(List<Long> ids) {
		return userRepository.findAllByIds(ids);
	}

	@Override
	public User findAllByName(String name) {
		return userRepository.findAllByName(name);
	}

}